/*-----------------------------------------------------------------------------
	The contents of this file are subject to the Mozilla Public License
	Version 1.1 (the "License"); you may not use this file except in
	compliance with the License. You may obtain a copy of the License at
	http://www.mozilla.org/MPL/
	
	Software distributed under the License is distributed on an "AS IS"
	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
	License for the specific language governing rights and limitations
	under the License.
	
	The Original Code is Fever Framework code.
	
	The Initial Developer of the Original Code is Romain Ecarnot.
	Portions created by Initial Developer are Copyright (C) 2006
	the Initial Developer. All Rights Reserved.
	
	Contributor(s):
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
-----------------------------------------------------------------------------*/

import org.aswing.ASColor;
import org.aswing.BorderLayout;
import org.aswing.colorchooser.ColorRectIcon;
import org.aswing.Component;
import org.aswing.geom.Point;
import org.aswing.Icon;
import org.aswing.JButton;
import org.aswing.JPanel;
import org.aswing.JTextField;
import org.aswing.LayoutManager;

import fever.app.local.Localisation;
import fever.app.local.LocalisationEvent;
import fever.app.local.LocalisationListener;
import fever.data.formatter.DateFormatter;
import fever.log.FeverDebug;
import fever.utils.Stringifier;

import fvaswing.components.datechooser.FvCalendarChooser;
import fvaswing.components.datechooser.FvCalendarListener;
import fvaswing.components.FvLabelButton;

/**
 * calendar basic field component.
 * 
 * <p>Use a textfield and a {@link fvaswing.components.FvCalendar} sub components.
 * 
 * <p>If you want to use auto validation process, take a look at 
 * {@link fvaswing.components.forms.FvDateField} component.
 * 
 * @author Romain Ecarnot
 */
class fvaswing.components.FvCalendarField extends JPanel implements FvCalendarListener, LocalisationListener
{
	//-------------------------------------------------------------------------
	// Private properties
	//-------------------------------------------------------------------------
	
	private var _field : JTextField;
	private var _button : FvLabelButton;
	private var _chooser : FvCalendarChooser;
	
	private var _maxYear : Number;
	private var _minYear : Number;	private var _showToday : Boolean;
	private var _formatter : DateFormatter;
	private var _date : Date;
	
		
	//-------------------------------------------------------------------------
	// Public API
	//-------------------------------------------------------------------------
	
	/**
	 * Constructor.
	 */
	public function FvCalendarField( )
	{
		super( new BorderLayout( 2, 0 ) );
		
		_maxYear = ( new Date() ).getFullYear() + 100;
		_minYear = 1900;		_showToday = true;
		_formatter = new DateFormatter();
		
		_configureUI();
		
		Localisation.addLocalisationListener( this );
	}
	
	/**
	 * Sets max year value.
	 */
	public function setMaximumYear( year : Number ) : Void
	{
		if( year > _minYear ) _maxYear = year;
	}
	
	/**
	 * Returns max year value.
	 */
	public function getMaximumYear() : Number
	{
		return _maxYear;	
	}
	
	/**
	 * Sets min year value.
	 */
	public function setMinimumYear( year : Number ) : Void
	{
		if( year < _maxYear ) _minYear = year;	
	}
	
	/**
	 * Returns min year value.
	 */
	public function getMinimumYear() : Number
	{
		return _minYear;	
	}
	
	/**
	 * Indicates if component highlight 'today' cell.<br />
	 * Default is {@code true}
	 */
	public function setShowTodayEnabled( b : Boolean ) : Void
	{
		_showToday = b;
	}
	
	/**
	 * Returns {@code true} if calendar highlight the 'today' cell.
	 */
	public function isShowTodayEnabled() : Boolean
	{
		return _showToday;	
	}
	
	/**
	 * Sets the formatting pattern to use when receive date from 
	 * {@link fvaswing.components.FvCalendar} component.
	 * 
	 * <p>Default is connected to the <strong>Localisation API</strong>
	 */
	public function setFormatPattern( pattern : String ) : Void
	{
		_formatter.formatString = pattern;
	}
	
	/**
	 * Returns used formatting pattern.
	 */
	public function getFormatPattern() : String
	{
		return _formatter.formatString;	
	}
	
	/**
	 * Connects instance to localisation API.<br />
	 * Automatically update the formatting pattern using localisation pattern definition.
	 */
	public function connectToLocalisation() : Void
	{
		_formatter.connectToLocalisation();	
	}
	
	/**
	 * Sets combobox selected item.
	 */
	public function setValue( date : Date ) : Void
	{
		if ( date != _date )
		{
			var year : Number = date.getFullYear();
			if( ( year >= _minYear ) && ( year <= _maxYear ) )
			{
				_date = date;
				_field.setText( _formatter.format( date ) );
			}
		}
	}
	
	/**
	 * Returns selected date.
	 */
	public function getValue() : Date
	{
		return _date;
	}
	
	/**
	 * Returns result in string format using textfield content.
	 */
	public function getText() : String
	{
		return _field.getText();	
	}
	
	/**
	 * Clears textfield.
	 */
	public function clear() : Void
	{
		_field.setText();
		_date = null;	
	}
	
	/**
	 * Sets button icon.
	 */
	public function setIcon( icon : Icon ) : Void
	{
		_button.setIcon( icon );	
	}
	
	/**
	 * Returns button icon.
	 */
	public function getIcon() : Icon
	{
		return _button.getIcon();	
	}
	
	/**
	 * Triggered when localisation change.
	 */
	public function onLocalisationUpdate( event : LocalisationEvent ) : Void
	{
		if( _field.getTextLength() > 0 ) _field.setText( _formatter.format( _date ) );
	}
	
	/**  
	 * Triggered by {@link fvaswing.components.FvCalendar}
	 * component when a date is selected.
	 */
	public function onCalendarClick ( date : Date ) : Void
	{
		_date = date;
		_field.setText( _formatter.format( date ) );	
	}
	
	/**
	 * Returns string representation.
	 */
	public function toString() : String
	{
		return Stringifier.parse( this );
	}
	
	
	//-------------------------------------------------------------------------
	// Private implementation
	//-------------------------------------------------------------------------
	
	private function _configureUI() : Void
	{
		_chooser = FvCalendarChooser.getInstance();
		_field = new JTextField();
		_field.setRestrict( '0-9/' );
		
		_button = new FvLabelButton( new ColorRectIcon( 16, 16, ASColor.GRAY ) );
		_button.setUseHandCursor( false );
		_button.addActionListener( _openChooser, this );
		
		super.insert( -1, _field, BorderLayout.CENTER);		super.insert( -1, _button, BorderLayout.EAST);
	}
	
	private function _openChooser( source : JButton ) : Void
	{
		var pos : Point = _button.getGlobalLocation();
		
		_chooser.setMinimumYear( _minYear );
		_chooser.setMaximumYear( _maxYear );
		_chooser.setShowTodayEnabled( _showToday );
		
		if( !_date ) _date = new Date();
		_chooser.setSelectedDate( _date );
		_chooser.connect( this );
		_chooser.setLocation( pos );
		
		_chooser.open();
	}
	
	/**
	 * Protected.
	 * 
	 * <p>Can't insert component into {@link FvCalendarField} component.
	 */
	private function insert( i : Number, com : Component, constraints : Object ) : Void
	{
		FeverDebug.ERROR( '.insert() is not available for ' + this );		
	}
	
	/**
	 * Protected.
	 * 
	 * <p>Can't insert component into {@link FvCalendarField} component.
	 */
	private function append( com : Component, constraints : Object ) : Void
	{		
		FeverDebug.ERROR( '.append() is not available for ' + this );
	}
	
	/**
	 * Protected.
	 * 
	 * <p>Can't modify {@link FvCalendarField} component layout.<br />
	 * Keep <strong>BorderLayout</strong> layout.
	 */
	private function setLayout( layout : LayoutManager ):Void
	{	
		FeverDebug.ERROR( '.setLayout() is not available for ' + this );	
	}
	
}